using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Web;
using System.IO.Compression;
using DNAide.IO;

namespace DNAide.Web.UI.Styles
{
	/// <summary></summary>
	public class StyleAideHandler : IHttpHandler
	{

		private object _lock = new object();
		private string _fileName;
		private string _filePhysicalPath;
		private HttpContext _context;
		private CompressionAlgorithmType _compressionAlgorithm;

		private string ETag
		{
			get { return Path.GetFileNameWithoutExtension(this._fileName); }
		}

		/// <summary>
		/// </summary>
		/// <param name="context"></param>
		public void ProcessRequest(HttpContext context)
		{
			this._fileName = context.Request.QueryString["file"];
			if (string.IsNullOrEmpty(this._fileName))
				throw new Exception("No file to process.");

			this._filePhysicalPath = context.Server.MapPath(StyleAide.CacheUrl + "/" + this._fileName);
			if (!File.Exists(this._filePhysicalPath))
				throw new Exception("File not found.");

			this._context = context;
			if (this._context.Request.QueryString["action"] == "compress")
			{
				this.DoCompress();
			}

		}


		private void DoCompress()
		{
			if (this.IsCachedOnBrowser())
				return;

			this.DetermineCompressionType();

			this._context.Response.ClearHeaders();
			this._context.Response.AppendHeader("Etag", this.ETag);
			this._context.Response.ContentType = DNAide.Configuration.DNAideConfigurationSettings.Web.StyleAide.MimeType;

			string fileToSend = this._filePhysicalPath;
			if (this._compressionAlgorithm == CompressionAlgorithmType.GZip)
			{
				this._context.Response.AppendHeader("Content-Encoding", "gzip");
				fileToSend += ".gz";
			}
			else
			{
				this._context.Response.AppendHeader("Content-Encoding", "deflate");
				fileToSend += ".z";
			}
			if (!File.Exists(fileToSend))
			{
				lock (this._lock)
				{
					if (!File.Exists(fileToSend))
					{
						FileAide.Compress(this._filePhysicalPath, fileToSend, this._compressionAlgorithm);
					}
				}
			}

			FileInfo fi = new FileInfo(fileToSend);
			this._context.Response.AppendHeader("Content-Length", fi.Length.ToString());
			this._context.Response.WriteFile(fileToSend);
		}



		private bool IsCachedOnBrowser()
		{
			if (RequestAide.IsCachedOnBrowser(this.ETag))
			{
				this._context.Response.ClearHeaders();
				this._context.Response.ContentType = DNAide.Configuration.DNAideConfigurationSettings.Web.StyleAide.MimeType;
				this._context.Response.AppendHeader("Etag", this.ETag);
				this._context.Response.Status = "304 Not Modified";
				this._context.Response.AppendHeader("Content-Length", "0");
				return true;
			}
			else
			{
				return false;
			}
		}


		private void DetermineCompressionType()
		{
			this._compressionAlgorithm = CompressionAlgorithmType.None;

			if (RequestAide.IsGZipSupported())
			{
				this._compressionAlgorithm = CompressionAlgorithmType.GZip;
			}
			else if (RequestAide.IsDeflateSupported())
			{
				this._compressionAlgorithm = CompressionAlgorithmType.Deflate;
			}
		}


		/// <summary></summary>
		public bool IsReusable
		{
			get { return false; }
		}


	}
}
